#include "BlockingQ.hpp"
#include "Task.hpp"
#include "lockGuard.hpp"

int add(int x, int y)
{
    return x + y;
}

void *Producer(void *args)
{
    BlockingQueue<Task> *bq = (BlockingQueue<Task> *)args;
    while (true)
    {
        int x = rand() % 100;
        int y = rand() % 100;
        bq->Push(Task(x, y, add)); // 生产任务
        cout << "[" << pthread_self() << "]Produce a Task: " << x << " + " << y << " = ?" << endl;
    }
}

void *Consumer(void *args)
{
    BlockingQueue<Task> *bq = (BlockingQueue<Task> *)args;
    while (true)
    {
        Task t;
        bq->Pop(t); // 获取任务
        cout << "[" << pthread_self() << "]consume a Task: " << t._x << " + " << t._y << " = " << t.cal() << endl;
        sleep(1);
    }
}

int main()
{
    srand((unsigned long)time(NULL) ^ getpid());
    BlockingQueue<Task> *Bq = new BlockingQueue<Task>; // 阻塞队列
    pthread_t p[2], c[2];

    // 多生产多消费
    pthread_create(p, NULL, Producer, (void *)Bq);
    pthread_create(p + 1, NULL, Producer, (void *)Bq); // 生产者线程
    pthread_create(c, NULL, Consumer, (void *)Bq);
    pthread_create(c + 1, NULL, Consumer, (void *)Bq); // 消费者线程，Bq作为参数传入

    pthread_join(p[0], NULL);
    pthread_join(p[1], NULL);
    pthread_join(c[0], NULL);
    pthread_join(c[1], NULL); // 等待子线程退出

    delete Bq; // 释放Bq资源
    return 0;
}